function TextureMgr( gl) {
    this._baseUri = "";
    this._texs = new Map();
    this._gl = gl;
}

function _onLoadedTexFromImage( gl, tex, isLinearSample) {
    gl.bindTexture( gl.TEXTURE_2D, tex);
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
    gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tex.image);
    if ( isLinearSample) {
        gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    }else {
        gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
        gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    }
    gl.bindTexture( gl.TEXTURE_2D, null);    
    tex.isOk = true;
    
    for ( var k in tex.callbacks) {
        tex.callbacks[k]( tex);
    }
    tex.callbacks = null;
}

TextureMgr.prototype = {
init : function( baseUri, gl) {
    this._baseUri = baseUri;
    if ( gl) this._gl = gl;
},

get : function( relPath, callback, isLinearSample) {
    var tex = this._texs.get(relPath);
    if ( tex == null) {
        // todo defernce formats: 8888 4444 565 5551
        tex = this._gl.createTexture();
        tex.isOk = false;
        tex.callbacks = new Array();
        if ( callback)
            tex.callbacks.push( callback);
        var gl = this._gl;
        tex.image = new Image();
        tex.image.onload = function () {
            _onLoadedTexFromImage( gl, tex, isLinearSample);
        }
        tex.image.src = this._baseUri + relPath;
        return null;
    }
    else if ( tex.isOk) {
        if ( callback) callback( tex);
        return tex;
    }
    else {
        if ( callback)
            tex.callbacks.push( callback);
        return null;
    }
},

};

mix.texMgr = new TextureMgr( mix.gl);